/*
 * Copyright (c) 2009 by unreserved.org.
 * All rights reserved.
 */

package org.unreserved.ladderplot;

import java.awt.*;
import java.awt.datatransfer.*;
import java.io.*;
import org.apache.log4j.ConsoleAppender;
import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import org.apache.log4j.PatternLayout;
import org.apache.log4j.RollingFileAppender;
import org.apache.log4j.varia.NullAppender;
import org.unreserved.util.*;

public class Main {
    private static final Logger logger = Logger.getLogger(Main.class);
    
    private static Logger lapLogger;
    private static ConsoleAppender sysout;
    
    private File input;
    private static boolean setClipboard = false;
    
    static void usage() {
        printHelp("usage.txt");
    }
    
    static void printHelp(String helpfile) {
        InputStream in = Main.class.getResourceAsStream(helpfile);
        if (in == null) {
            System.err.println("Failed to load file: " + helpfile);
        } else {
            try {
                copyAll(in, System.out);
                in.close();
            } catch (IOException _) {}
        }
    }
    
    static void copyAll(InputStream in, OutputStream out) throws IOException {
        int b;
        while ((b = in.read()) >= 0) {
            out.write(b);
        }
    }
    
    static void err(String s) {
        System.err.println("Error: " + s);
    }
    
    static void err_usage(String msg) {
        if (msg != null) {
            err(msg);
        }
        usage();
        System.exit(1);
    }
    
    public static void main(String[] args) {
        // make log4j be quiet by default
        Logger log4jRoot = Logger.getRootLogger();
        if (!log4jRoot.getAllAppenders().hasMoreElements()) {
            log4jRoot.addAppender(new NullAppender());
        }
        
        // add ConsoleAppender to "org.unreserved" logger
        PatternLayout sysoutLayout = new PatternLayout("%-5p %c{1}: %m%n");
        sysout = new ConsoleAppender(sysoutLayout, "System.out");
        lapLogger = Logger.getLogger("org.unreserved");
        lapLogger.addAppender(sysout);
        lapLogger.setLevel(Level.WARN);
        lapLogger.setAdditivity(false);
        
        logger.info(Version.FULL_INFO);
        
        try {
            Main main = new Main();
            main.init(args);
            main.run();
        } catch (Throwable t) {
            logger.error("", t);
            System.err.println("error: " + t);
            System.exit(1);
        }
    }
    
    private Main() {
    }
    
    private void init(String[] args) throws IOException {
        int i;
        for (i = 0; i < args.length; i++) {
            if (args[i].equals("-h")) {
                usage();
                System.exit(0);
            } else if (args[i].equals("-version")) {
                System.out.println(Version.FULL_INFO);
                System.exit(0);
            } else if (args[i].equals("-v")) {
                lapLogger.setLevel(Level.DEBUG);
            } else if (args[i].equals("-l")) {
                // log to the specified file
                if (++i >= args.length) {
                    err_usage("-l option requires an argument");
                }
                PatternLayout layout = new PatternLayout("%-5p %d{ABSOLUTE} [%t] %c{1}: %m%n");
                RollingFileAppender fileApp = new RollingFileAppender(layout, args[i], false);
                fileApp.setMaxBackupIndex(1);
                fileApp.setMaximumFileSize(1024*1024); // 1 MB
                lapLogger.addAppender(fileApp);
                logger.info("logging to file: " + args[i]);
            } else if ("-c".equals(args[i])) {
                setClipboard = true;
            } else if (args[i].startsWith("-")) {
                err_usage("Unrecognized option: " + args[i]);
            } else {
                break;
            }
        }
        
        if (i != args.length - 1) {
            err_usage(null);
        }
        
        input = new File(args[i]);
    }
    
    protected void run() throws IOException, PropertySetterException {
        try {
            Model model = new LapReader().parse(input);
            ModelTextRenderer tr = new ModelTextRenderer(model);
            tr.render();
            TextCanvas canvas = tr.getCanvas();
            BufferedWriter out = new BufferedWriter(new OutputStreamWriter(System.out));
            canvas.print(out);
            out.flush();
            // this stmt makes Sub JVM (1.5.0_11) terminate with ZERO
            // output when run from logplot. No exception, no nothing!
            //out.close();
            
            logger.debug("setting clipboard...");
            if (setClipboard) {
                setClipboard(canvas.toString());
            }
        } catch (IOException ex) {
            logger.error("fatal error", ex);
            err(ex.getMessage());
        } catch (LapParseException ex) {
            logger.error("fatal error", ex);
            err(ex.getMessage());
        }
    }
    
    static void setClipboard(String s) {
        Toolkit tk = Toolkit.getDefaultToolkit() ;
        Clipboard cb = tk.getSystemClipboard();
        cb.setContents(new StringSelection(s), null);
    }
}
